#ifdef _DEBUG_
#include <iostream>
using namespace std;
#endif

#include <unistd.h>

#include "edaWrapperControl.h"
#include "edaSearchWrapper.h"

edaWrapperControl::edaWrapperControl() :
  edgeNum (0), vertexNum (0)
{
}

int edaWrapperControl::insertVertex(edaSearch *sa)
{
  int id = vertexNum;
  vertexNum++;

  taskDAG.insertVertex(id, sa);
  taskStatus[id] = STATUS_PENDING;

  return id;
}

int edaWrapperControl::insertEdge(const int from, const int to)
{
  int id = edgeNum;
  edgeNum++;

  taskDAG.insertEdge(id, from, to);

  printDebug(4, "parent of [" << to << "] is [" << from <<"]");

  return id;
}

vector<int> edaWrapperControl::findReadyNodes() const
{
  vector<int> nodeList;
  vector<int> readyNodes;
  vector<int>::iterator intIter;

  nodeList = taskDAG.traverse();
  for (intIter = nodeList.begin(); intIter != nodeList.end(); intIter++)
  {
    // Check if the node is not in PENDING state
    map<int, int>::const_iterator mci = taskStatus.find(*intIter);
    if (mci->second != STATUS_PENDING)
    {
      // Then bypass
      continue;
    }

    // Find parents node
    vector<int> parentNodes;
    parentNodes = taskDAG.getParentNodes(*intIter);

    // Check parent nodes that all nodes is FINISHED
    vector<int>::iterator parentIter;
    bool allFinished = true;
    for (parentIter = parentNodes.begin(); parentIter != parentNodes.end(); parentIter++)
    {
      mci = taskStatus.find(*parentIter);
      if (mci->second != STATUS_FINISHED)
      {
        allFinished = false;
        break;
      }
    }

    if (allFinished)
    {
      readyNodes.push_back(*intIter);
    }
  }

  return readyNodes;
}

bool edaWrapperControl::allDone() const
{
  vector<int> nodeList;
  vector<int>::iterator intIter;
  nodeList = taskDAG.traverse();

  for (intIter = nodeList.begin(); intIter != nodeList.end(); intIter++)
  {
    map<int, int>::const_iterator mci = taskStatus.find(*intIter);

    if (mci->second != STATUS_FINISHED)
    {
      printDebug(5, "not done: " << mci->first);

      return false;
    }
  }

  return true;
}
